home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xrobots / game.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  8KB  |  350 lines

  1. /*
  2.  * game.c -- xrobots
  3.  * 
  4.  * Copyright 1989 Brian Warkentine
  5.  * 
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the author's name not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  The author makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  * 
  16.  * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
  17.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE 
  18.  * AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 
  19.  * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
  20.  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
  21.  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  * 
  23.  * The author's current employer has no connection with this software, as it
  24.  * was written before being employed at Sun.  The following address is for 
  25.  * contacting the author only and does not imply any responsibility on the 
  26.  * behalf of Sun Microsystems.
  27.  * 
  28.  * Contact the author at:
  29.  *     Brian Warkentine  (brianw@Sun.COM)
  30.  *     Sun Microsystems
  31.  *     2550 Garcia Avenue
  32.  *     Mountain View, Ca 94043-1100
  33.  *
  34.  */
  35.  
  36. #include <X11/Intrinsic.h>
  37. #include "xrobots.h"
  38.  
  39. /* some of these are global */
  40. int human_x, human_y, last_human_x, last_human_y;
  41.  
  42. int robot_array[MAXX][MAXY],
  43.     robot_array_bak[MAXX][MAXY];    
  44.     /* These arrays are filled with the robots and the heaps 
  45.      * They do not include the player(human).
  46.      */
  47. int    score,
  48.     num_robots,
  49.     level,
  50.     game_active,
  51.     sonic_used;
  52.  
  53. static void autochase();
  54.  
  55. /*----------------------------------------------------------------------*/
  56. void
  57. new_game()
  58. {
  59.   score = 0;
  60.   level = 0;
  61.   sonic_used = 1;
  62.   game_active = 1;
  63.   new_level();
  64.   update_score(score);
  65. }
  66.  
  67. /*----------------------------------------------------------------------*/
  68. void
  69. add_score(n)
  70.   int n;
  71. {
  72.   score += 10 * n; /* ten points for each wasted robot. */
  73.   num_robots -= n;
  74.   if(n) update_score(score);
  75. }
  76.  
  77. /*----------------------------------------------------------------------*/
  78. void
  79. new_level()
  80. {
  81.   int x,y,tmp;
  82.  
  83.   reset_sonic_button();
  84.   if(!sonic_used) {
  85.     score += 50;     /* bonus for not using sonic screwdriver on last level*/
  86.     update_score(score);
  87.   }
  88.   sonic_used = 0;
  89.   level++;
  90.   num_robots = tmp = level*5;
  91.  
  92.   for_each                            /* clean out both the robot arrays */
  93.   {
  94.     robot_array[x][y] = EMPTY;
  95.     robot_array_bak[x][y] = EMPTY;
  96.   }
  97.   
  98.   human_x = (int)random()%MAXX;                  /* assign human to new space */
  99.   human_y = (int)random()%MAXY;
  100.   robot_array[human_x][human_y] = ROBOT;
  101.  
  102.   while(tmp--)
  103.   {
  104.     x = (int)random()%MAXX;
  105.     y = (int)random()%MAXY;
  106.     if(robot_array[x][y] == ROBOT) tmp++;        /* space already occupied */
  107.     robot_array[x][y] = ROBOT;
  108.   }
  109.   robot_array[human_x][human_y] = EMPTY;
  110.   display_level();
  111.   display_possible_moves();
  112. }
  113.  
  114. /*----------------------------------------------------------------------*/
  115. int
  116. chase()
  117. {
  118.   /* chase() returns the number of robots that were wasted in each call. */
  119.   /* after each call, be sure to check if all the robots are dead */
  120.   int x,y;
  121.   int newx,newy;
  122.   int num_wasted = 0;
  123.  
  124.   for_each
  125.   {
  126.     robot_array_bak[x][y] = robot_array[x][y];
  127.     if(robot_array[x][y] != HEAP)
  128.       robot_array[x][y] = 0;
  129.   }
  130.  
  131.   for_each
  132.   {
  133.     if(robot_array_bak[x][y] != ROBOT)
  134.       continue;
  135.  
  136.     if(x>human_x)                           /* move toward the human */
  137.       newx = x-1;
  138.     else  
  139.       if(x<human_x)
  140.         newx = x+1;
  141.       else
  142.         newx = x;
  143.  
  144.     if(y>human_y) 
  145.       newy = y-1;
  146.     else  
  147.       if(y<human_y)
  148.         newy = y+1;
  149.       else
  150.         newy = y;
  151.  
  152. #   ifdef DEBUG
  153.     printf("moving (%d,%d) to (%d,%d)\n",x,y,newx,newy);
  154. #   endif
  155.  
  156.     /* check to see if a robot or heap was already in that spot */
  157.     if(robot_array[newx][newy] == ROBOT)
  158.     {
  159.       robot_array[newx][newy] = HEAP;
  160.       num_wasted += 2;
  161.       continue;
  162.     }
  163.     if(robot_array[newx][newy] == HEAP)
  164.     {
  165.       num_wasted++;
  166.       continue;
  167.     }
  168.     /* move robot to new location */
  169.     robot_array[newx][newy] = ROBOT;
  170.   }
  171.  
  172.   return(num_wasted);
  173. }
  174.  
  175. /*----------------------------------------------------------------------*/
  176. void
  177. undo_chase()
  178. {
  179.   int x,y;
  180.   for_each
  181.     robot_array[x][y] = robot_array_bak[x][y];
  182. }
  183.  
  184. /*----------------------------------------------------------------------*/
  185. void
  186. teleport()
  187. {
  188.   int num_wasted;
  189.  
  190.   if(!game_active) return;
  191.   do
  192.   {
  193.     human_x = (int)random()%MAXX;        /* pick a spot not already occupied */
  194.     human_y = (int)random()%MAXY;
  195.   }
  196.   while(robot_array[human_x][human_y] != EMPTY);
  197.  
  198.   show_teleport();
  199.  
  200.   num_wasted = chase(0);
  201.  
  202.   if(robot_array[human_x][human_y] != EMPTY)
  203.   {
  204.     /* death... */
  205.     undo_chase();    
  206.     /* it is a matter of preference to clear the screen when you die... */
  207.     display_level();
  208.     do_death();
  209.     check_score(score);
  210.     game_active = 0;
  211.     return;
  212.   }
  213.  
  214.   display_level();
  215.  
  216.   score += num_robots;       /* bonus for teleporting */
  217.   score += num_wasted * 10;  /* score for any that collided */
  218.   num_robots -= num_wasted;
  219.   update_score(score);
  220.  
  221.   if(!num_robots) 
  222.     new_level();
  223.   else 
  224.     display_possible_moves();
  225.   auto_teleport();
  226.   XFlush(display);
  227. }
  228.  
  229. /*----------------------------------------------------------------------*/
  230. void
  231. sonic_screwdriver()
  232. {
  233.   /*
  234.    * a trick - remove the neighboring robots by calling chase() and 
  235.    * letting them crash into each other in the human's spot, then clear out 
  236.    * the human's position of the remains.
  237.    */
  238.   int num_wasted;
  239.  
  240.   if(!game_active) return;
  241.   if(sonic_used) return;
  242.   sonic_used = 1;
  243.   show_sonic();
  244.   num_wasted = chase(1);
  245.   if(robot_array[human_x][human_y] == ROBOT)
  246.     add_score(1);
  247.   robot_array[human_x][human_y] = EMPTY;
  248.  
  249.   last_human_x = human_x;
  250.   last_human_y = human_y;
  251.   show_movement();
  252.  
  253.   add_score(num_wasted);
  254.   if(!num_robots) 
  255.     new_level();
  256.   else 
  257.     display_possible_moves();
  258.   auto_teleport();
  259.   XFlush(display);
  260. }
  261.  
  262. /*----------------------------------------------------------------------*/
  263. void
  264. wait_for_em()
  265. {
  266.   /*
  267.    * the trick - call chase() until any robot is in the same spot as the
  268.    * human, then backout as if the last chase() didn't happen.
  269.    */
  270.   int num_wasted;
  271.  
  272.   if(!game_active) return;
  273.  
  274.   while(1) {
  275.     num_wasted = chase(1);
  276.     if(robot_array[human_x][human_y] != EMPTY) {
  277.       /* backout of latest chase() and break loop */
  278.       undo_chase();
  279.  
  280.       if(diewaiting) {      /* for those risk takers out there */
  281.         display_level();
  282.         do_death();
  283.         check_score(score);
  284.         game_active = 0;
  285.         return;
  286.       }
  287.  
  288.       break;
  289.     }
  290.     add_score(num_wasted);
  291.     if(!num_robots)
  292.     break;
  293.     if(showjumps)
  294.       show_movement();
  295.     XFlush(display);
  296.   }
  297.   if(!num_robots) 
  298.     new_level();
  299.   else
  300.     if(!showjumps)
  301.       display_level();
  302.   display_possible_moves();
  303.   auto_teleport();
  304.   XFlush(display);
  305. }
  306.  
  307. /*----------------------------------------------------------------------*/
  308.  
  309.  
  310. int
  311. can_go(x,y)
  312.   int x,y;
  313. {
  314. /* check if (x,y) is a legit move. */
  315.   if( INYRANGE(y-1) ) {
  316.     if( INXRANGE(x-1) )
  317.       if(robot_array[x-1][y-1] == ROBOT)  return 0;
  318.     if( INXRANGE(x) )
  319.       if(robot_array[x][y-1] == ROBOT)  return 0;
  320.     if( INXRANGE(x+1) )
  321.       if(robot_array[x+1][y-1] == ROBOT)  return 0;
  322.   }
  323.  
  324.   if( INYRANGE(y) ) {
  325.     if( INXRANGE(x-1) )
  326.       if(robot_array[x-1][y] == ROBOT)  return 0;
  327.     if( INXRANGE(x) ) {
  328.       if(robot_array[x][y] == ROBOT)  return 0;
  329.       if(robot_array[x][y] == HEAP)   return 0;
  330.       }
  331.     if( INXRANGE(x+1) )
  332.       if(robot_array[x+1][y] == ROBOT)  return 0;
  333.   }
  334.  
  335.   if( INYRANGE(y+1) ) {
  336.     if( INXRANGE(x-1) )
  337.       if(robot_array[x-1][y+1] == ROBOT)  return 0;
  338.     if( INXRANGE(x) )
  339.       if(robot_array[x][y+1] == ROBOT)  return 0;
  340.     if( INXRANGE(x+1) )
  341.       if(robot_array[x+1][y+1] == ROBOT)  return 0;
  342.   }
  343.  
  344.   if( !INXRANGE(x) )  return 0;
  345.   if( !INYRANGE(y) )  return 0;
  346.  
  347.   return 1;
  348. }
  349.  
  350.